﻿
// DuplicateMessageDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "DuplicateMessage.h"
#include "DuplicateMessageDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include "EditTextDlg.h"


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CDuplicateMessageDlg 对话框



CDuplicateMessageDlg::CDuplicateMessageDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DUPLICATEMESSAGE_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDuplicateMessageDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	//  DDX_Text(pDX, IDC_ClickNumber, clickNumberInput);
	//  DDX_Control(pDX, IDC_ClickNumber, clickNumber);
	//  DDX_Text(pDX, IDC_ClickNumber, clickNumber);
	DDX_Control(pDX, IDC_ClickNumber, clickNumberInput);
}

BEGIN_MESSAGE_MAP(CDuplicateMessageDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_BN_CLICKED(IDC_Perform, &CDuplicateMessageDlg::OnBnClickedPerform)
	ON_BN_CLICKED(IDC_Cancel, &CDuplicateMessageDlg::OnBnClickedCancel)
	ON_BN_CLICKED(IDC_PastText, &CDuplicateMessageDlg::OnBnClickedPasttext)
	ON_STN_CLICKED(IDC_EditText, &CDuplicateMessageDlg::OnStnClickedEdittext)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CDuplicateMessageDlg 消息处理程序

BOOL CDuplicateMessageDlg::OnInitDialog()
{
	
	this->SetWindowTextW(_T("鼠标连点"));
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	HICON TITLE= AfxGetApp()->LoadIcon(IDI_title);
	SetIcon(TITLE,true);
	SetIcon(TITLE, false);

	data->windowHwndTextHwnd = GetDlgItem(IDC_WindowHwndText);
	data->windowNameTextHwnd = GetDlgItem(IDC_WindowNameText);
	data->pointTextHwnd = GetDlgItem(IDC_PointText);
	data->remainingClickNumber = GetDlgItem(IDC_ClickNumber);
	data->clickNumber = 0;
	data->textBoxPoint = GetDlgItem(IDC_TextBoxPoint);
	data->showSendButtonPoint = GetDlgItem(IDC_SendButtonPoint);
	CreateThread(NULL, 0, MouseWindowsPosition, data, 0, NULL);

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CDuplicateMessageDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CDuplicateMessageDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDuplicateMessageDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

bool cursorPointStatus = false;

DWORD CDuplicateMessageDlg::OnlyClickPerform(LPVOID lpParameter)
{
	Sleep(5000);
	struct tempData {
		CWnd* windowNameTextHwnd;
		CWnd* windowHwndTextHwnd;
		CWnd* pointTextHwnd;
		CWnd* remainingClickNumber;
		std::vector<CString>* waitInputText;
		CWnd* textBoxPoint;
		CWnd* showSendButtonPoint;
		int clickNumber;
	};
	tempData* tempdata = (tempData*)(lpParameter);

	HWND hwndPointNow = NULL;
	POINT pNow = { 0,0 };
	CString outputRemainingClickNumber;
	while (1) {
		Sleep(10);
		GetCursorPos(&pNow); // 获取鼠标当前位置
		hwndPointNow = *WindowFromPoint(pNow); // 获取鼠标所在窗口的句柄
		CWnd* cWnd = CWnd::FromHandle(hwndPointNow);
		cWnd->ScreenToClient(&pNow);
		LPARAM lParam = MAKELPARAM(pNow.x, pNow.y);
		
		/*
		::OpenClipboard(hwndPointNow);
		::EmptyClipboard();  //清空剪贴板，使该窗口成为剪贴板的拥有者  
		CString str("fdsfds");//将文本放置到系统剪贴板中  
		HGLOBAL hClip;
		//判断要是文本数据，分配内存时多分配一个字符  
		hClip = ::GlobalAlloc(GMEM_MOVEABLE, (str.GetLength() * 2) + 2);
		TCHAR* pBuf;
		pBuf = (TCHAR*)::GlobalLock(hClip);//锁定剪贴板  
		lstrcpy(pBuf, str);//把CString转换  
		::GlobalUnlock(hClip);//解除锁定剪贴板  
		::SetClipboardData(CF_UNICODETEXT, hClip);//把文本数据发送到剪贴板  CF_UNICODETEXT为Unicode编码  
		::CloseClipboard();//关闭剪贴板  
		*/
		//::PostMessage(hwndPointNow, WM_PASTE,0,0);
		//::SendMessage(hwndPointNow, WM_CHAR, 0, (WPARAM)('g'));
		//::SendMessage(hwndPointNow, WM_PASTE, 0,0);

		/*
		::SendMessage(hwndPointNow, WM_LBUTTONDOWN, MK_LBUTTON, lParam222);
		::SendMessage(hwndPointNow, WM_LBUTTONUP, MK_LBUTTON, lParam222);

		::SendMessage(hwndPointNow, WM_PASTE, 0, 0);
		*/
		::SendMessage(hwndPointNow, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
		::SendMessage(hwndPointNow, WM_LBUTTONUP, MK_LBUTTON, lParam);
		
		if (--tempdata->clickNumber<0) { break; }
		outputRemainingClickNumber.Format(_T("%d"), tempdata->clickNumber);
		tempdata->remainingClickNumber->SetWindowTextW(outputRemainingClickNumber);
		if (!cursorPointStatus) {
			break;
		}
	}
	
	return 0;
}

DWORD CDuplicateMessageDlg::PastTextPerform(LPVOID lpParameter) {

	struct tempData {
		CWnd* windowNameTextHwnd;
		CWnd* windowHwndTextHwnd;
		CWnd* pointTextHwnd;
		CWnd* remainingClickNumber;
		std::vector<CString>* waitInputText;
		CWnd* textBoxPoint;
		CWnd* showSendButtonPoint;
		int clickNumber;
	};
	tempData* tempdata = (tempData*)(lpParameter);

	std::vector<CString>::iterator iter;
	iter = tempdata->waitInputText->begin();

	AfxMessageBox(_T("点击确认按键后，请把鼠标放至文本编辑框三秒"), MB_OK);
	POINT EditBoxPoint= { 0,0 };
	POINT sendPoint = { 0,0 };
	CString showPoint;
	for (int i = 0; i < 30; i++) {
		GetCursorPos(&EditBoxPoint);
		showPoint.Format(_T("编辑框位置   X:%d  Y:%d"), EditBoxPoint.x, EditBoxPoint.y);
		tempdata->textBoxPoint->SetWindowTextW(showPoint);
		Sleep(100);
	}
	AfxMessageBox(_T("点击确认后，请把鼠标放至发送按钮三秒"), MB_OK);

	for (int i = 0; i < 30; i++) {
		GetCursorPos(&sendPoint);
		showPoint.Format(_T("发送按钮位置   X:%d  Y:%d"), sendPoint.x, sendPoint.y);
		tempdata->showSendButtonPoint->SetWindowTextW(showPoint);
		Sleep(100);
	}

	
	AfxMessageBox(_T("点击确认后，程序将在五秒钟后执行，单击鼠标右键终止！！！"), MB_OK);
	Sleep(5000);
	HWND hwndPointNow = NULL;
	hwndPointNow = *WindowFromPoint(sendPoint); // 获取鼠标所在窗口的句柄
	CWnd* cWnd = CWnd::FromHandle(hwndPointNow);
	cWnd->ScreenToClient(&sendPoint);
	LPARAM lParam = MAKELPARAM(sendPoint.x, sendPoint.y);

	cWnd->ScreenToClient(&EditBoxPoint);
	LPARAM  EditBox = MAKELPARAM(EditBoxPoint.x, EditBoxPoint.y);


	srand((int)time(0));
	int random=0;
	CString outputRemainingClickNumber;
	while (1) {
		Sleep(10);



		 random = rand() % tempdata->waitInputText->size();

		::OpenClipboard(hwndPointNow);
		::EmptyClipboard();  //清空剪贴板，使该窗口成为剪贴板的拥有者
		CString str(*(iter+random));//将文本放置到系统剪贴板中
		HGLOBAL hClip;
		//判断要是文本数据，分配内存时多分配一个字符
		hClip = ::GlobalAlloc(GMEM_MOVEABLE, (str.GetLength() * 2) + 2);
		TCHAR* pBuf;
		pBuf = (TCHAR*)::GlobalLock(hClip);//锁定剪贴板
		lstrcpy(pBuf, str);//把CString转换
		::GlobalUnlock(hClip);//解除锁定剪贴板
		::SetClipboardData(CF_UNICODETEXT, hClip);//把文本数据发送到剪贴板  CF_UNICODETEXT为Unicode编码
		::CloseClipboard();//关闭剪贴板
		
		
		
		mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, EditBoxPoint.x * 65535 / 1920, EditBoxPoint.y * 65535 / 1080, 0, 0);//移动到需要点击的位置
		//mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE, EditBoxPoint.x * 65535 / 1920, EditBoxPoint.y * 65535 / 1080, 0, 0);//点击
		//mouse_event(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE, EditBoxPoint.x * 65535 / 1920, EditBoxPoint.y * 65535 / 1080, 0, 0);//点击
		
		::SendMessage(hwndPointNow, WM_LBUTTONDOWN, MK_LBUTTON, EditBox);
		::SendMessage(hwndPointNow, WM_LBUTTONUP, MK_LBUTTON, EditBox);
		::SendMessage(hwndPointNow, WM_PASTE, 0, 0);
		mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, sendPoint.x * 65535 / 1920, sendPoint.y * 65535 / 1080, 0, 0);//移动到需要点击的位置
		//mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, sendPoint.x * 65535 / 1920, sendPoint.y * 65535 / 1080, 0, 0);
		//mouse_event(MOUSEEVENTF_LEFTUP	 | MOUSEEVENTF_LEFTUP, sendPoint.x * 65535 / 1920, sendPoint.y * 65535 / 1080, 0, 0);
		::SendMessage(hwndPointNow, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
		::SendMessage(hwndPointNow, WM_LBUTTONUP, MK_LBUTTON, lParam);
		if (--tempdata->clickNumber < 0) { break; }
		outputRemainingClickNumber.Format(_T("%d"), tempdata->clickNumber);
		tempdata->remainingClickNumber->SetWindowTextW(outputRemainingClickNumber);
		if (!cursorPointStatus) {
			break;
		}
	}
	return 0;
}

CString CDuplicateMessageDlg::char_CString(char* ch)
{
	CString temp;
	int charLen = strlen(ch);
	//计算多字节字符的大小，按字符计算。
	int len = MultiByteToWideChar(CP_ACP, 0, ch, charLen, NULL, 0);
	//为宽字节字符数组申请空间，数组大小为按字节计算的多字节字符大小
	TCHAR* buf = new TCHAR[(unsigned __int64)len + 1];
	//多字节编码转换成宽字节编码
	MultiByteToWideChar(CP_ACP, 0, ch, charLen, buf, len);
	buf[len] = '\0'; //添加字符串结尾，注意不是len+1
	//将TCHAR数组转换为CString
	temp.Append(buf);
	//删除缓冲区
	delete[]buf;
	return temp;
}



void CDuplicateMessageDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CDialogEx::OnRButtonDown(nFlags, point);
}

DWORD CDuplicateMessageDlg::MouseWindowsPosition(LPVOID lpParameter) {
	struct tempData {
		CWnd* windowNameTextHwnd;
		CWnd* windowHwndTextHwnd;
		CWnd* pointTextHwnd;
		CWnd* remainingClickNumber;
		std::vector<CString>* waitInputText;
		CWnd* textBoxPoint;
		int clickNumber;
	};
	tempData* tempdata = (tempData*)(lpParameter);
	HWND hwndPointNow = NULL;
	POINT pNow = { 0,0 };
	char WindowTitle[100];
	CString windowHwndText;
	CString pNowText;

	while (1) {
		Sleep(100);
		GetCursorPos(&pNow); // 获取鼠标当前位置
		hwndPointNow = *WindowFromPoint(pNow); // 获取鼠标所在窗口的句柄

		::GetWindowTextA(hwndPointNow, WindowTitle, sizeof(WindowTitle)); // 获取窗口标题
		tempdata->windowNameTextHwnd->SetWindowTextW(char_CString(WindowTitle));

		windowHwndText.Format(_T("%d"), hwndPointNow);
		tempdata->windowHwndTextHwnd->SetWindowTextW(windowHwndText);

		pNowText.Format(_T("鼠标位置   X:%d  Y:%d"), pNow.x, pNow.y);
		tempdata->pointTextHwnd->SetWindowTextW(pNowText);
	}
	return 0;
}

void CDuplicateMessageDlg::OnBnClickedPerform()
{
	CString clickNumber;
	clickNumberInput.GetWindowTextW(clickNumber);
	data->clickNumber = _ttoi(clickNumber);
	data->waitInputText = &waitInputText;

	switch (this->IsDlgButtonChecked(IDC_PastText))
	{
	case BST_CHECKED:
		threadHANDLE = CreateThread(NULL, 0, PastTextPerform , data, 0, NULL);
		break;
	case BST_UNCHECKED:
		threadHANDLE = CreateThread(NULL, 0, OnlyClickPerform, data, 0, NULL);
		break;
	}

	SetTimer(1, 100, NULL);
	cursorPointStatus = true;
}


void CDuplicateMessageDlg::OnBnClickedCancel()
{
	cursorPointStatus = false;
}


void CDuplicateMessageDlg::OnBnClickedPasttext()
{
	if (waitInputText.empty()) {
		CDuplicateMessageDlg::OnStnClickedEdittext();
	}
}


void CDuplicateMessageDlg::OnStnClickedEdittext()
{
	struct editTextData {
		std::vector<CString>* waitInputText;
	};
	editTextData* edittextdata = new editTextData();
	edittextdata->waitInputText =&waitInputText;
	EditTextDlg* ED = new EditTextDlg(edittextdata);
	ED->Create(IDD_EditTextDlg);
	ED->ShowWindow(SW_SHOWNORMAL);
	UpdateData(true);
}


void CDuplicateMessageDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nIDEvent) {
	case 1:
		if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) {
			cursorPointStatus = false;
		}
		break;
	}
	CDialogEx::OnTimer(nIDEvent);
}
